package net.crashtoot.picasa.gui.downloader;
/*
    This file is part of Picasa Album Downloader.

    Picasa Album Downloader is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Picasa Album Downloader is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Picasa Album Downloader.  If not, see <http://www.gnu.org/licenses/>.
 */
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;

import javax.swing.SwingUtilities;

import com.google.gdata.data.photos.AlbumEntry;
import com.google.gdata.data.photos.PhotoEntry;

/**
 * 
 * @author Stanislav Ochotnicky <sochotnicky@gmail.com>
 * 
 *         Class for downloading the albums and loading albums.
 * 
 *         Depending on purpose the constructor can have 2. parameter of type:
 *         WorkerType.ALBUM_LOADER, or WorkerType.ALBUM_DOWNLOADER
 * 
 * 
 * 
 */
public class WorkerThread extends Thread {
	private final PicasaDlApplet applet;

	public enum WorkerType {
		ALBUM_LOADER, ALBUM_DOWNLOADER
	};

	private String startMessage;
	private String finishMessage;
	private WorkerType type;
	private Object data;
	private File outputDirectory;
	private int progress;
	private int progressMax;
	private boolean started;
	private boolean finished;

	public WorkerThread(final PicasaDlApplet applet, WorkerType type,
			Object data, File outputDir) {
		started = false;
		finished = false;
		this.applet = applet;
		this.type = type;
		this.data = data;
		this.outputDirectory = outputDir;
		if (type == WorkerType.ALBUM_LOADER) {
			startMessage = "loading albums...";
			finishMessage = "finished loading albums";

		} else {
			startMessage = "starting download";
			finishMessage = "finished download";
		}
	}

	private void setStatus(String message) {
		final String s = message;
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				applet.setStatus(s);
			}
		});
	}

	private void updateProgress() {
		final WorkerThread thr = this;
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				applet.updateProgress(thr);
			}
		});
	}

	private void addAlbum(AlbumEntry album) {
		final AlbumEntry a = album;
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				applet.addAlbum(a);
			}
		});
	}

	@SuppressWarnings("unchecked")
	@Override
	public void run() {
		try {
			started = true;
			setStatus(startMessage);
			if (type == WorkerType.ALBUM_LOADER) {
				List<AlbumEntry> albums = (List<AlbumEntry>) data;

				for (AlbumEntry myAlbum : albums) {
					addAlbum(myAlbum);

					System.out.println(myAlbum.getTitle().getPlainText());
				}
			} else {
				List<PhotoEntry> photos = (List<PhotoEntry>) data;
				progress = 0;
				progressMax = photos.size();
				for (PhotoEntry photo : photos) {
					setStatus("downloading photo "
							+ photo.getTitle().getPlainText());
					savePhoto(outputDirectory, photo);
					progress++;
					updateProgress();
				}

			}
			setStatus(finishMessage);
		} catch (Exception ex) {
			System.err.println(ex);
		}
		finished = true;
	}

	private void savePhoto(File directory, PhotoEntry photo)
			throws FileNotFoundException, MalformedURLException, IOException {
		FileOutputStream fos = new FileOutputStream(directory.getAbsolutePath()
				+ File.separator + photo.getTitle().getPlainText());
		URL fileUrl = new URL(photo.getMediaContents().get(0).getUrl());

		InputStream dis = fileUrl.openStream();

		int readCount = 0;
		byte b[] = new byte[8096];
		while ((readCount = dis.read(b)) != 0 && readCount != -1) {
			fos.write(b, 0, readCount);
		}
		dis.close();
		fos.close();
	}

	public double getProgress() {
		if (started && !finished)
			return (double) progress / (double) progressMax;
		else if (started)
			return 1;
		else
			return 0;
	}
}
